<template>
  <div id="content">
    <div id="canvas"></div>
    <div id="saveDiagram">
      <el-button type="primary" @click="saveDiagram">保存模型</el-button>
      <li>
        <a ref="saveDiagram" title="download BPMN diagram">BPMN diagram</a>
      </li>
      <li>
        <a ref="saveSvg" title="download as SVG image">SVG image</a>
      </li>
    </div>
  </div>
</template>

<script>
import BpmnModeler from 'bpmn-js/lib/Modeler';
import {Message} from "element-ui";
import X2JS from 'x2js'

export default {
  name: 'BpmnEditor',
  methods: {
    saveDiagram() {
      console.log(this.xml)
      Message.success("保存成功");
    },
    async init(xml){
      try {
        const result = await this.modeler.importXML(xml);
        const { warnings } = result;
        console.log(warnings);
      } catch (err) {
        console.log(err.message, err.warnings);
      }
    }
  },
  async saveXML(options){

    try {
      const result = await this.modeler.saveXML(options);
      const { xml } = result;
      console.log(xml);
    } catch (err) {
      console.log(err);
    }
  },
  // 下载为SVG格式,done是个函数，调用的时候传入的
  saveSVG(done) {
    // 把传入的done再传给bpmn原型的saveSVG函数调用
    this.saveXML(done);
  },
  // 下载为SVG格式,done是个函数，调用的时候传入的
  saveDiagram(done) {
    // 把传入的done再传给bpmn原型的saveXML函数调用
    this.saveXML(done);
  },

  // 当图发生改变的时候会调用这个函数，这个data就是图的xml
  setEncoded(link, name, data) {
    // 把xml转换为URI，下载要用到的
    const encodedData = encodeURIComponent(data);
    // 获取到图的xml，保存就是把这个xml提交给后台
    this.xmlStr = data;
    console.log(this.xmlStr);
    // 下载图的具体操作,改变a的属性，className令a标签可点击，href令能下载，download是下载的文件的名字
    if (data) {
      link.className = "active";
      link.href = "data:application/bpmn20-xml;charset=UTF-8," + encodedData;
      link.download = name;
    }
  },
  mounted() {
    this.modeler = new BpmnModeler({
      container: '#canvas'
    });

    // 初始化一个空的BPMN图
    const emptyDiagram = `<?xml version="1.0" encoding="UTF-8"?>
    <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.12.0">
      <bpmn:process id="Process_1" isExecutable="true">
        <bpmn:startEvent id="StartEvent_1" />
      </bpmn:process>
      <bpmndi:BPMNDiagram id="BPMNDiagram_1">
        <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
          <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
            <dc:Bounds x="173" y="102" width="36" height="36" />
          </bpmndi:BPMNShape>
        </bpmndi:BPMNPlane>
      </bpmndi:BPMNDiagram>
    </bpmn:definitions>`;
    this.xml = emptyDiagram;

    this.init(emptyDiagram);
    // 给图绑定事件，当图有发生改变就会触发这个事件
    const downloadLink = this.$refs.saveDiagram;
    const downloadSvgLink = this.$refs.saveSvg;

    this.modeler.on("commandStack.changed", () => {
      this.saveSVG(function (err, svg) {
        this.setEncoded(downloadSvgLink, "diagram.svg", err ? null : svg);
      });

      this.saveDiagram( (err, xml) => {
        this.setEncoded(downloadLink, "diagram.bpmn", err ? null : xml);
      });
    });
  }
}
</script>

<style scoped lang="scss">
#canvas {
  width: 100%;
  height: 100vh;
}
#content{
  position: relative;
}
#saveDiagram {
  position: absolute;
  top: 10px;
  right: 10px;
}
</style>
